Skip to content

feat(calm-hub-ui): mobile responsive layouts for CALM Hub UI#2700

Merged
jpgough-ms merged 19 commits into
finos:mainfrom
rocketstack-matt:claude/calm-hub-ui-mobile-responsive-vrquce
Jun 21, 2026
Merged

feat(calm-hub-ui): mobile responsive layouts for CALM Hub UI#2700
jpgough-ms merged 19 commits into
finos:mainfrom
rocketstack-matt:claude/calm-hub-ui-mobile-responsive-vrquce

Conversation

@rocketstack-matt

@rocketstack-matt rocketstack-matt commented Jun 20, 2026

Copy link
Copy Markdown
Member

Description

Makes the CALM Hub UI mobile responsive. The Hub, Visualizer, architecture diagram, explorer navigation, timeline, and control-detail views previously assumed a desktop viewport and were largely unusable on a phone. This reworks the layouts so the whole app is touch-friendly on small screens, without changing the desktop experience.

Highlights (all mobile-only unless noted):

  • Responsive Hub and Visualizer layouts driven by a useIsMobile breakpoint hook.
  • Explorer moved into the top navbar with an iOS-style drill-down menu; Hub/Visualizer nav links and the in-canvas zoom controls removed on mobile.
  • Full-bleed architecture render pane; the view-options (Diagram / JSON / Deployments), component search, and timeline all live in a single navbar menu. Timeline is a full-screen, iOS-style drill-down: the current moment shows a forward chevron when more versions exist, tapping pushes a newest-first list of all versions, and selecting one navigates the diagram.
  • Menus and detail panels are full-screen push overlays rather than float-overs.
  • Centred CALM logo and device safe-area (notch) handling in the navbar.
  • Control detail view becomes tabbed (Requirement / Configuration) and reformatted for narrow screens.

Closes #2698

Type of Change

  • ✨ New feature (non-breaking change which adds functionality)

Affected Components

  • CALM Hub UI (calm-hub-ui/)

Testing

  • I have tested my changes locally
  • I have added/updated unit tests
  • All existing tests pass

npm run lint, npm test (779 tests) and npm run build all pass for calm-hub-ui.

Checklist

  • My commits follow the conventional commit format
  • I have updated documentation if necessary
  • I have added tests for my changes (if applicable)
  • My changes follow the project's coding standards

Screenshots

Desktop (unchanged) Mobile — diagram Mobile — view menu
Mobile — explorer Mobile — search Mobile — node detail
Mobile — timeline Mobile — timeline list
Mobile — control requirement Mobile — control configuration

The Hub used a rigid three-column flex layout (tree navigation, content,
details panel) with fixed/percentage widths that could not fit on phones
or tablet-portrait viewports.

- Add a useMediaQuery/useIsMobile hook (test-safe; guards window.matchMedia)
- Hub: below the lg breakpoint the tree navigation becomes an off-canvas
  drawer with a dimmed backdrop, toggled by an "Explore" button; the
  details Sidebar becomes a full-screen overlay. Desktop behaviour is
  unchanged.
- Sidebar (details panel): responsive width (w-full on mobile, w-96 on lg+)
- GlobalSearchBar: responsive input width and viewport-bounded dropdown
- SectionHeader: allow the breadcrumb and tabs to wrap instead of overflowing
- Compare view: stack the two diff graphs vertically on narrow viewports
- Add matchMedia polyfill to the vitest setup and tests for the new hook
  and the Hub mobile drawer behaviour

Signed-off-by: Matthew Bain <matt@rocketstack.co>
Follow-up to the responsive layout work, focused on the diagram experience
and a regression it exposed.

- Fix mobile data-loading regression: the URL deep-link / global-search
  loading lives inside TreeNavigation, which was unmounted on mobile until
  the drawer opened, so direct links and search results loaded nothing. The
  mobile drawer now keeps TreeNavigation mounted and slides it off-canvas
  via transform instead of unmounting.
- Hide the minimap on mobile in the single (ArchitectureGraph/PatternGraph)
  and compare (DiffGraph) views — it was oversized and overlapped the canvas.
- Collapse the node search/type-filter bar to a single icon on mobile,
  expanding on tap.
- Tuck the timeline behind a floating clock button that opens it as a bottom
  sheet (TimelineBar gains an initialExpanded prop for the sheet), instead of
  permanently occupying the short viewport.
- Make the diagram tabs icon-only on mobile and trim the Explore trigger so
  the section header stops wrapping to extra lines.

Signed-off-by: Matthew Bain <matt@rocketstack.co>
On mobile the tree-navigation ("Explore") menu and the node/relationship
detail panel were partial floating cards over a dimmed backdrop. Promote
them to full-screen panels that slide in (the menu from the left, the
detail from the right), each dismissed via its own header control rather
than a backdrop tap.

- Hub: tree-navigation panel is now fixed inset-0 full-screen (kept mounted
  and slid off-canvas so deep-link/search loading still runs); the details
  overlay is full-screen with a slide-in-right animation and no backdrop.
- Sidebar: drop the card padding/rounding/shadow on mobile so it fills the
  screen edge-to-edge; keep the desktop card (lg:p-4 / lg:rounded-box).
- Add a slide-in-right keyframe utility for the detail push animation.
- Update the Hub mobile tests to assert open/closed via the dialog role.

Signed-off-by: Matthew Bain <matt@rocketstack.co>
Replace the nested expanding tree with a native-style drill-down on mobile:
each tap pushes the next level as a flat list (Namespaces -> namespace ->
resource type -> resource; Control Domains -> domain -> control), with a
back button to pop a level and a leaf tap that loads the resource.

- Add MobileNavMenu: a self-contained drill-down navigator that fetches each
  level on demand, navigates to the chosen resource URL, and (like the desktop
  tree) loads deep-linked / globally-searched resources via a URL-params effect
  so direct links still work on mobile.
- Extract the shared resource-loading/version-resolution helpers into
  navigation-loaders.ts, consumed by both TreeNavigation (desktop) and
  MobileNavMenu (mobile), removing the duplicated logic.
- Hub: render MobileNavMenu in the mobile panel (TreeNavigation stays for
  desktop); the menu closes itself when a resource is chosen.
- Tests for MobileNavMenu drill-down/back/deep-link; update Hub mobile tests.

Signed-off-by: Matthew Bain <matt@rocketstack.co>
…mobile zoom controls

- Navbar: remove the Hub and Visualizer links. Add an "Explore" button (shown
  when the page provides a handler) that toggles the explorer.
- Hub: the navbar Explore button opens the mobile drill-down panel on mobile
  and toggles the desktop sidebar on desktop; remove the in-content Explore
  button. The Visualizer keeps no nav links (reachable via /visualizer).
- Diagram: hide the ReactFlow zoom controls on mobile (single, pattern, and
  compare views) — pinch-to-zoom is the native touch interface; controls remain
  on desktop.
- Tests: Navbar mock exposes the Explore toggle; add a desktop navbar-toggle
  test; update mobile tests accordingly.

Signed-off-by: Matthew Bain <matt@rocketstack.co>
…plorer search

- Diagram: make the render pane full-bleed (drop the section-header bar and card
  chrome) and move the Diagram/JSON/Deployments switch plus the breadcrumb into a
  hamburger menu pinned to the top-right of the canvas. Offset the in-canvas node
  search so it clears the menu.
- Mobile search: add an always-visible search bar to the mobile explorer
  (MobileNavMenu); while a query is present the results take over the explorer
  body. Search stays in the navbar on desktop (hidden below lg), unchanged.
- Add ExplorerSearch (inline, takeover results) alongside the existing
  navbar GlobalSearchBar.
- Tests for ExplorerSearch; stub it in the MobileNavMenu test; adjust the
  DiagramSection view-mode assertions for the new menu.

Signed-off-by: Matthew Bain <matt@rocketstack.co>
Open the diagram's view-options (breadcrumb + Diagram/JSON/Deployments) as a
full-screen overlay on mobile, consistent with the explorer and detail panels,
instead of a small dropdown. Desktop keeps the dropdown.

Signed-off-by: Matthew Bain <matt@rocketstack.co>
The view-options hamburger no longer floats over the render pane; it is
portalled into a navbar slot (#navbar-actions) so it sits in the top nav on
both mobile and desktop. Falls back to inline rendering when no navbar slot is
present (e.g. in isolated component tests).

Signed-off-by: Matthew Bain <matt@rocketstack.co>
…view icon

Desktop keeps its original section header with inline Diagram/JSON/Deployments
tabs and card chrome — the full-bleed render pane, navbar view-options menu and
full-screen view overlay now apply on mobile only. The mobile navbar trigger
shows the icon of the currently active view instead of a generic hamburger.

Signed-off-by: Matthew Bain <matt@rocketstack.co>
…menu

On mobile the in-canvas node search is replaced by a "Search components"
section inside the view-options menu. A NodeSearchProvider context lets the
menu drive the graph's search/type-filter without prop-drilling; the graph
hides its in-canvas search bar when the context is external. Desktop and the
standalone Visualizer keep the in-canvas search (graph-local state).

Signed-off-by: Matthew Bain <matt@rocketstack.co>
Centre the CALM logo in the navbar, respect device safe-area insets so the
bar never slides under the notch or overflows the viewport, restyle the
mobile view-options menu to match the explorer rows, and fold the timeline
action into that menu instead of a separate navbar button.

Signed-off-by: Matthew Bain <matt@rocketstack.co>
Replace the bottom-sheet timeline with a full-screen overlay that matches
the view-options menu chrome (header bar with title and close button),
giving the moment list and change details the full viewport on mobile.

Signed-off-by: Matthew Bain <matt@rocketstack.co>
On mobile, present the control's Requirement and Configuration as two tabs
instead of stacked panels, and reformat each pane (stacked header, view
toggle, and horizontally scrollable version pickers) to suit narrow
screens. Desktop keeps the existing two-panel layout.

Signed-off-by: Matthew Bain <matt@rocketstack.co>
@github-actions github-actions Bot added the calm-hub-ui Affects `calm-hub-ui` label Jun 20, 2026
…mobile-responsive-vrquce

Signed-off-by: Matthew Bain <matt@rocketstack.co>

# Conflicts:
#	calm-hub-ui/index.html
#	calm-hub-ui/src/hub/components/tree-navigation/TreeNavigation.tsx
…h renders

Add a Responsive Design section covering the useIsMobile breakpoint hook, the
mobile-only-must-not-change-desktop rule, and the established mobile patterns
(full-screen overlays, navbar-hosted actions, drill-down explorer, tabbed
detail views, safe-area handling). Strengthen the Testing section to require
verifying both desktop and mobile renders, with the matchMedia mocking pattern
for unit tests.

Signed-off-by: Matthew Bain <matt@rocketstack.co>
@rocketstack-matt rocketstack-matt marked this pull request as ready for review June 20, 2026 16:07
@rocketstack-matt rocketstack-matt requested a review from a team as a code owner June 20, 2026 16:07
Copilot AI review requested due to automatic review settings June 20, 2026 16:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds mobile-responsive behavior across CALM Hub UI by introducing a shared useIsMobile breakpoint hook and reworking navigation, diagram controls, and detail views to be touch-friendly on small screens while aiming to preserve the desktop layout.

Changes:

  • Introduces useMediaQuery / useIsMobile plus a jsdom matchMedia polyfill and associated unit tests.
  • Reworks Hub navigation for mobile (full-screen drill-down explorer + explorer-hosted search) and updates diagram/timeline/view menus for mobile overlays.
  • Adjusts Visualizer/ReactFlow components (minimap/controls/search) to behave appropriately on mobile, including shared node-search state via context.

Reviewed changes

Copilot reviewed 29 out of 29 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
calm-hub-ui/vitest.setup.ts Adds matchMedia polyfill for jsdom to support responsive tests.
calm-hub-ui/src/visualizer/components/sidebar/Sidebar.tsx Makes sidebar responsive (full-width on mobile, fixed width on desktop).
calm-hub-ui/src/visualizer/components/reactflow/SearchBar.tsx Adds mobile “collapsed-to-icon” behavior and forceExpanded mode.
calm-hub-ui/src/visualizer/components/reactflow/PatternGraph.tsx Uses shared node-search context and hides minimap/controls on mobile.
calm-hub-ui/src/visualizer/components/reactflow/node-search-context.tsx Adds context for externally-managed node search state (mobile view menu).
calm-hub-ui/src/visualizer/components/reactflow/ArchitectureGraph.tsx Uses shared node-search context and hides minimap/controls on mobile.
calm-hub-ui/src/index.css Adds slide-in animation utility for mobile push overlays.
calm-hub-ui/src/hub/Hub.tsx Adds mobile explorer overlay + mobile detail sidebar overlay; wires navbar “Explore”.
calm-hub-ui/src/hub/Hub.test.tsx Adds desktop/navbar explorer toggle test and mobile drill-down panel tests.
calm-hub-ui/src/hub/components/tree-navigation/TreeNavigation.tsx Extracts URL/type mapping and loading helpers to shared module.
calm-hub-ui/src/hub/components/tree-navigation/navigation-loaders.ts New shared loader/mapping helpers used by both desktop and mobile nav.
calm-hub-ui/src/hub/components/tree-navigation/MobileNavMenu.tsx New iOS-style drill-down navigation for mobile, including deep-link loading.
calm-hub-ui/src/hub/components/tree-navigation/MobileNavMenu.test.tsx Unit tests for drill-down navigation and deep-link loading behavior.
calm-hub-ui/src/hub/components/section-header/SectionHeader.tsx Improves header wrapping/padding for narrow viewports.
calm-hub-ui/src/hub/components/diagram-section/timeline/TimelineBar.tsx Adds initialExpanded to support mobile timeline sheet without persisting state.
calm-hub-ui/src/hub/components/diagram-section/DiagramSection.tsx Adds mobile view-options menu + navbar-portal actions + full-screen timeline overlay + external node search.
calm-hub-ui/src/hub/components/control-detail-section/ControlDetailSection.tsx Adds mobile tabbed Requirement/Configuration layout; refactors shared UI builders.
calm-hub-ui/src/hub/components/control-detail-section/ControlDetailSection.test.tsx Adds tests for new mobile tabbed control detail layout.
calm-hub-ui/src/hooks/useMediaQuery.ts New responsive breakpoint hook (useIsMobile at Tailwind lg).
calm-hub-ui/src/hooks/useMediaQuery.test.ts Unit tests for media-query hook behavior and updates.
calm-hub-ui/src/diff/Diff.css Adds mobile stacking layout for compare panels.
calm-hub-ui/src/diff/components/DiffGraph.tsx Hides minimap/controls on mobile for diff graphs.
calm-hub-ui/src/components/navbar/Navbar.tsx Reworks navbar layout (center logo, explorer toggle, navbar action portal, hide global search on mobile).
calm-hub-ui/src/components/navbar/Navbar.css Makes logo shrinkable and adds safe-area padding.
calm-hub-ui/src/components/navbar/GlobalSearchBar.tsx Shrinks input on narrow viewports and bounds dropdown width.
calm-hub-ui/src/components/navbar/ExplorerSearch.tsx New explorer-hosted search with debounce, keyboard nav, and grouped inline results.
calm-hub-ui/src/components/navbar/ExplorerSearch.test.tsx Unit tests for explorer search debounce/results/keyboard/error handling.
calm-hub-ui/index.html Enables viewport-fit=cover for iOS safe-area support.
calm-hub-ui/AGENTS.md Documents responsive patterns, useIsMobile usage, and expectations for testing desktop+mobile.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread calm-hub-ui/src/components/navbar/Navbar.tsx Outdated
Comment thread calm-hub-ui/src/components/navbar/Navbar.tsx Outdated
Comment thread calm-hub-ui/src/components/navbar/ExplorerSearch.tsx Outdated
Comment thread calm-hub-ui/src/components/navbar/ExplorerSearch.tsx
Comment thread calm-hub-ui/src/hooks/useMediaQuery.ts Outdated
Comment thread calm-hub-ui/src/diff/Diff.css
Address Copilot review feedback: reorder handleClear above handleKeyDown and
add it to the dependency array instead of disabling react-hooks/exhaustive-deps
(the project forbids suppressing that rule), and memoise flatResults so the
keyboard-handler dependencies stay stable.

Signed-off-by: Matthew Bain <matt@rocketstack.co>
@markscott-ms

Copy link
Copy Markdown
Contributor

Screenshots look good!

- Restore desktop Hub (logo) home link and Visualizer nav link removed by the
  responsive rework; the logo is now a router Link (keyboard-navigable).
- Resolve the latest resource version via pickLatestVersion instead of assuming
  the service returns versions in order.
- Fall back to MediaQueryList.addListener on browsers without addEventListener.
Replace the horizontally-scrolling moment cards with an iOS-style drill-down
on mobile: the detail level shows the currently-viewed moment with a forward
chevron and version count, tapping pushes a newest-first list of all versions,
and selecting one navigates the diagram and pops back. Desktop keeps the
inline TimelineBar. Compare-from/to is not exposed on touch for now (it was
right-click only).
@jpgough-ms jpgough-ms merged commit 7d9f915 into finos:main Jun 21, 2026
17 checks passed
rocketstack-matt pushed a commit to rocketstack-matt/architecture-as-code that referenced this pull request Jun 21, 2026
A `node_modules` symlink was accidentally committed to the repo root in
PR finos#2700 (commit 7d9f915). It pointed at an absolute path on the author's
machine (/Users/matthewbain/.../node_modules), so it was meaningless to
everyone else and dirtied fresh clones.

Two changes:
- Remove the tracked `node_modules` symlink.
- Fix `.gitignore`: the entry `node_modules/` carried a trailing slash,
  which makes git ignore only *directories* named node_modules. Git stores
  symlinks as files (mode 120000), so the symlink never matched the
  directory-only pattern and slipped through. Dropping the trailing slash
  makes the pattern match a node_modules directory, file, or symlink at any
  depth, preventing a recurrence.

Fixes finos#2707

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B1zsESbpQPxsFH3nsg9n6m
rocketstack-matt added a commit to rocketstack-matt/architecture-as-code that referenced this pull request Jun 21, 2026
A `node_modules` symlink was accidentally committed to the repo root in
PR finos#2700 (commit 7d9f915). It pointed at an absolute path on the author's
machine (/Users/matthewbain/.../node_modules), so it was meaningless to
everyone else and dirtied fresh clones.

Two changes:
- Remove the tracked `node_modules` symlink.
- Fix `.gitignore`: the entry `node_modules/` carried a trailing slash,
  which makes git ignore only *directories* named node_modules. Git stores
  symlinks as files (mode 120000), so the symlink never matched the
  directory-only pattern and slipped through. Dropping the trailing slash
  makes the pattern match a node_modules directory, file, or symlink at any
  depth, preventing a recurrence.

Fixes finos#2707
jpgough-ms pushed a commit to jpgough-ms/architecture-as-code that referenced this pull request Jun 22, 2026
)

* feat(calm-hub-ui): make Hub and Visualizer layouts mobile responsive

The Hub used a rigid three-column flex layout (tree navigation, content,
details panel) with fixed/percentage widths that could not fit on phones
or tablet-portrait viewports.

- Add a useMediaQuery/useIsMobile hook (test-safe; guards window.matchMedia)
- Hub: below the lg breakpoint the tree navigation becomes an off-canvas
  drawer with a dimmed backdrop, toggled by an "Explore" button; the
  details Sidebar becomes a full-screen overlay. Desktop behaviour is
  unchanged.
- Sidebar (details panel): responsive width (w-full on mobile, w-96 on lg+)
- GlobalSearchBar: responsive input width and viewport-bounded dropdown
- SectionHeader: allow the breadcrumb and tabs to wrap instead of overflowing
- Compare view: stack the two diff graphs vertically on narrow viewports
- Add matchMedia polyfill to the vitest setup and tests for the new hook
  and the Hub mobile drawer behaviour

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* feat(calm-hub-ui): make the architecture/diagram view usable on mobile

Follow-up to the responsive layout work, focused on the diagram experience
and a regression it exposed.

- Fix mobile data-loading regression: the URL deep-link / global-search
  loading lives inside TreeNavigation, which was unmounted on mobile until
  the drawer opened, so direct links and search results loaded nothing. The
  mobile drawer now keeps TreeNavigation mounted and slides it off-canvas
  via transform instead of unmounting.
- Hide the minimap on mobile in the single (ArchitectureGraph/PatternGraph)
  and compare (DiffGraph) views — it was oversized and overlapped the canvas.
- Collapse the node search/type-filter bar to a single icon on mobile,
  expanding on tap.
- Tuck the timeline behind a floating clock button that opens it as a bottom
  sheet (TimelineBar gains an initialExpanded prop for the sheet), instead of
  permanently occupying the short viewport.
- Make the diagram tabs icon-only on mobile and trim the Explore trigger so
  the section header stops wrapping to extra lines.

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* feat(calm-hub-ui): make mobile menu and detail panels full-screen

On mobile the tree-navigation ("Explore") menu and the node/relationship
detail panel were partial floating cards over a dimmed backdrop. Promote
them to full-screen panels that slide in (the menu from the left, the
detail from the right), each dismissed via its own header control rather
than a backdrop tap.

- Hub: tree-navigation panel is now fixed inset-0 full-screen (kept mounted
  and slid off-canvas so deep-link/search loading still runs); the details
  overlay is full-screen with a slide-in-right animation and no backdrop.
- Sidebar: drop the card padding/rounding/shadow on mobile so it fills the
  screen edge-to-edge; keep the desktop card (lg:p-4 / lg:rounded-box).
- Add a slide-in-right keyframe utility for the detail push animation.
- Update the Hub mobile tests to assert open/closed via the dialog role.

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* feat(calm-hub-ui): iOS-style drill-down navigation on mobile

Replace the nested expanding tree with a native-style drill-down on mobile:
each tap pushes the next level as a flat list (Namespaces -> namespace ->
resource type -> resource; Control Domains -> domain -> control), with a
back button to pop a level and a leaf tap that loads the resource.

- Add MobileNavMenu: a self-contained drill-down navigator that fetches each
  level on demand, navigates to the chosen resource URL, and (like the desktop
  tree) loads deep-linked / globally-searched resources via a URL-params effect
  so direct links still work on mobile.
- Extract the shared resource-loading/version-resolution helpers into
  navigation-loaders.ts, consumed by both TreeNavigation (desktop) and
  MobileNavMenu (mobile), removing the duplicated logic.
- Hub: render MobileNavMenu in the mobile panel (TreeNavigation stays for
  desktop); the menu closes itself when a resource is chosen.
- Tests for MobileNavMenu drill-down/back/deep-link; update Hub mobile tests.

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* feat(calm-hub-ui): move explorer into the navbar; drop nav links and mobile zoom controls

- Navbar: remove the Hub and Visualizer links. Add an "Explore" button (shown
  when the page provides a handler) that toggles the explorer.
- Hub: the navbar Explore button opens the mobile drill-down panel on mobile
  and toggles the desktop sidebar on desktop; remove the in-content Explore
  button. The Visualizer keeps no nav links (reachable via /visualizer).
- Diagram: hide the ReactFlow zoom controls on mobile (single, pattern, and
  compare views) — pinch-to-zoom is the native touch interface; controls remain
  on desktop.
- Tests: Navbar mock exposes the Explore toggle; add a desktop navbar-toggle
  test; update mobile tests accordingly.

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* feat(calm-hub-ui): full-bleed render pane, view-modes menu, mobile explorer search

- Diagram: make the render pane full-bleed (drop the section-header bar and card
  chrome) and move the Diagram/JSON/Deployments switch plus the breadcrumb into a
  hamburger menu pinned to the top-right of the canvas. Offset the in-canvas node
  search so it clears the menu.
- Mobile search: add an always-visible search bar to the mobile explorer
  (MobileNavMenu); while a query is present the results take over the explorer
  body. Search stays in the navbar on desktop (hidden below lg), unchanged.
- Add ExplorerSearch (inline, takeover results) alongside the existing
  navbar GlobalSearchBar.
- Tests for ExplorerSearch; stub it in the MobileNavMenu test; adjust the
  DiagramSection view-mode assertions for the new menu.

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* feat(calm-hub-ui): full-screen view-options menu on mobile

Open the diagram's view-options (breadcrumb + Diagram/JSON/Deployments) as a
full-screen overlay on mobile, consistent with the explorer and detail panels,
instead of a small dropdown. Desktop keeps the dropdown.

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* feat(calm-hub-ui): move the diagram view-options menu into the navbar

The view-options hamburger no longer floats over the render pane; it is
portalled into a navbar slot (#navbar-actions) so it sits in the top nav on
both mobile and desktop. Falls back to inline rendering when no navbar slot is
present (e.g. in isolated component tests).

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* fix(calm-hub-ui): keep the diagram redesign mobile-only; show active view icon

Desktop keeps its original section header with inline Diagram/JSON/Deployments
tabs and card chrome — the full-bleed render pane, navbar view-options menu and
full-screen view overlay now apply on mobile only. The mobile navbar trigger
shows the icon of the currently active view instead of a generic hamburger.

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* feat(calm-hub-ui): move component (node) search into the mobile view menu

On mobile the in-canvas node search is replaced by a "Search components"
section inside the view-options menu. A NodeSearchProvider context lets the
menu drive the graph's search/type-filter without prop-drilling; the graph
hides its in-canvas search bar when the context is external. Desktop and the
standalone Visualizer keep the in-canvas search (graph-local state).

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* feat(calm-hub-ui): mobile navbar polish and timeline in view menu

Centre the CALM logo in the navbar, respect device safe-area insets so the
bar never slides under the notch or overflows the viewport, restyle the
mobile view-options menu to match the explorer rows, and fold the timeline
action into that menu instead of a separate navbar button.

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* feat(calm-hub-ui): make mobile timeline a full-screen view

Replace the bottom-sheet timeline with a full-screen overlay that matches
the view-options menu chrome (header bar with title and close button),
giving the moment list and change details the full viewport on mobile.

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* feat(calm-hub-ui): tabbed mobile layout for control detail view

On mobile, present the control's Requirement and Configuration as two tabs
instead of stacked panels, and reformat each pane (stacked header, view
toggle, and horizontally scrollable version pickers) to suit narrow
screens. Desktop keeps the existing two-panel layout.

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* docs(calm-hub-ui): document responsive design and require testing both renders

Add a Responsive Design section covering the useIsMobile breakpoint hook, the
mobile-only-must-not-change-desktop rule, and the established mobile patterns
(full-screen overlays, navbar-hosted actions, drill-down explorer, tabbed
detail views, safe-area handling). Strengthen the Testing section to require
verifying both desktop and mobile renders, with the matchMedia mocking pattern
for unit tests.

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* fix(calm-hub-ui): remove exhaustive-deps suppression in ExplorerSearch

Address Copilot review feedback: reorder handleClear above handleKeyDown and
add it to the dependency array instead of disabling react-hooks/exhaustive-deps
(the project forbids suppressing that rule), and memoise flatResults so the
keyboard-handler dependencies stay stable.

Signed-off-by: Matthew Bain <matt@rocketstack.co>

* fix(calm-hub-ui): address Copilot review feedback on navbar and search

- Restore desktop Hub (logo) home link and Visualizer nav link removed by the
  responsive rework; the logo is now a router Link (keyboard-navigable).
- Resolve the latest resource version via pickLatestVersion instead of assuming
  the service returns versions in order.
- Fall back to MediaQueryList.addListener on browsers without addEventListener.

* feat(calm-hub-ui): mobile timeline drill-down list

Replace the horizontally-scrolling moment cards with an iOS-style drill-down
on mobile: the detail level shows the currently-viewed moment with a forward
chevron and version count, tapping pushes a newest-first list of all versions,
and selecting one navigates the diagram and pops back. Desktop keeps the
inline TimelineBar. Compare-from/to is not exposed on touch for now (it was
right-click only).

---------

Signed-off-by: Matthew Bain <matt@rocketstack.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

calm-hub-ui Affects `calm-hub-ui`

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Responsive mobile layout for CALM Hub UI

4 participants